package com.ai.module.mj.service.impl;

import com.ai.module.chat.config.advice.exception.BusinessException;
import com.ai.module.chat.util.DateUtils;
import com.ai.module.chat.util.RedisTemplateUtils;
import com.ai.module.mj.domain.Task;
import com.ai.module.mj.domain.dto.TaskCondition;
import com.ai.module.mj.service.LowTaskStoreService;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
public class RedisSlowTaskStoreServiceImpl implements LowTaskStoreService {

	@Resource
	private  RedisTemplate<String, Task> redisTemplate;
	private int maxQueue = 0;
	private AtomicInteger endNumber = new AtomicInteger(0);
	@Override
	public void save(Task task) {
		this.redisTemplate.opsForValue().set(getRedisKey(task.getId()), task, this.timeout);
	}

	@Override
	public void delete(String id) {
		this.redisTemplate.delete(getRedisKey(id));
	}

	@Override
	public Task get(String id) {
		return this.redisTemplate.opsForValue().get(getRedisKey(id));
	}

	@Override
	public List<Task> list() {
		Set<String> keys = this.redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
			Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().match(KEY_PREFIX + "*").count(1000).build());
			return cursor.stream().map(String::new).collect(Collectors.toSet());
		});
		if (keys == null || keys.isEmpty()) {
			return Collections.emptyList();
		}
		ValueOperations<String, Task> operations = this.redisTemplate.opsForValue();
		return keys.stream().map(operations::get)
				.filter(Objects::nonNull)
				.collect(Collectors.toList());
	}

	@Override
	public List<Task> list(TaskCondition condition) {
		return list().stream().filter(condition).collect(Collectors.toList());
	}

	@Override
	public Task findOne(TaskCondition condition) {
		return list().stream().filter(condition).findFirst().orElse(null);
	}

	private String getRedisKey(String id) {
		return KEY_PREFIX + id;
	}

	@Override
	public void saveEndTask(Task task) {
		int endQueue = endNumber.get();
		if (endQueue > maxQueue){
			throw new BusinessException("队列数据太多,请待会再尝试画画");
		}
		endNumber.getAndAdd(1);
		RedisTemplateUtils.lSet(SLOW_END_TASK_KEY,task, DateUtils.TIME_DAY *3 );
	}
}
